﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace LiveCodeServer
{
    public partial class ServerForm : Form
    {
        private ClientHandler clientHandler;
        private bool bOnline = false;

        public ServerForm()
        {
            InitializeComponent();
        }

        private void connectToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                if (!this.bOnline)
                {
                    if (this.clientHandler == null)
                    {
                        this.clientHandler = new ClientHandler(this);
                    }
                    else
                    {
                        this.clientHandler.GoOnline();
                    }

                    this.lbToolStriplServerStatus.Text = "Server Status: Online";
                    this.connectToolStripMenuItem.Text = "Go Offline";
                    this.serverStatusStrip.BackColor = Color.Yellow;
                    this.bOnline = true;
                }
                else
                {
                    if (this.clientHandler != null)
                    {
                        this.clientHandler.GoOffline();
                    }

                    this.lbToolStriplServerStatus.Text = "Server Status: Offline";
                    this.connectToolStripMenuItem.Text = "Go Online";
                    this.serverStatusStrip.BackColor = Color.Red;
                    this.bOnline = false;
                }
            }
            catch (Exception ex)
            {
                //TODO handle better

                string message = "Method: ServerForm.connectToolStripMenuItem_Click";
                message += "\nException: " + ex.Message;

                this.AddMessage(message, System.Drawing.Color.Red);
            }
        }

        public void UpdateUsersConnected(int iUsersConnected)
        {
            try
            {
                this.lblToolStripUsersConnected.Text = "Users Connected: " + iUsersConnected.ToString();

                if (iUsersConnected > 0)
                {
                    this.serverStatusStrip.BackColor = Color.LightGreen;
                }
                else if (iUsersConnected == 0 && this.bOnline)
                {
                    this.serverStatusStrip.BackColor = Color.Yellow;
                }
                else
                {
                    this.serverStatusStrip.BackColor = Color.Red;
                }
            }
            catch (Exception e)
            {
                //TODO handle better

                string message = "Method: ServerForm.UpdateUsersConnected";
                message += "\nException: " + e.Message;

                this.AddMessage(message, System.Drawing.Color.Red);
            }
        }

        private delegate void UserConnectedCallback(int iUserID, string sUsername);

        public void UserConnected(int iUserID, string sUsername)
        {
            try
            {
                if (this.InvokeRequired)
                {
                    UserConnectedCallback callback = new UserConnectedCallback(UserConnected);
                    this.Invoke(callback, new object[] { iUserID, sUsername });
                    return;
                }

                ListViewItem newRow = this.lvUsers.Items.Add(iUserID.ToString(), iUserID.ToString(), -1);
                newRow.SubItems.Add(sUsername);
            }
            catch (Exception e)
            {
                //TODO handle better

                string message = "Method: ServerForm.UserConnected";
                message += "\nException: " + e.Message;

                this.AddMessage(message, System.Drawing.Color.Red);
            }
            
        }

        private delegate void UserDisconnectedCallback(int iUserID);

        public void UserDisconnected(int iUserID)
        {
            try
            {
                if (this.InvokeRequired)
                {
                    UserDisconnectedCallback callback = new UserDisconnectedCallback(UserDisconnected);
                    this.Invoke(callback, new object[] { iUserID });
                    return;
                }

                if (this.lvUsers.Items.ContainsKey(iUserID.ToString()))
                {
                    this.lvUsers.Items.Remove(this.lvUsers.Items.Find(iUserID.ToString(), false)[0]);
                }
            }
            catch (Exception e)
            {
                //TODO handle better

                string message = "Method: ServerForm.UserDisconnected";
                message += "\nException: " + e.Message;

                this.AddMessage(message, System.Drawing.Color.Red);
            }
        }

        private delegate void ProjectLoginCallback(int iUserID, int iProjectID);

        public void ProjectLogin(int iUserID, int iProjectID)
        {
            try
            {
                if (this.InvokeRequired)
                {
                    ProjectLoginCallback callback = new ProjectLoginCallback(ProjectLogin);
                    this.Invoke(callback, new object[] { iUserID, iProjectID });
                    return;
                }

                this.lvUsers.Items[iUserID.ToString()].SubItems.Add(iProjectID.ToString());
            }
            catch (Exception e)
            {
                //TODO handle better

                string message = "Method: ServerForm.ProjectLogin";
                message += "\nException: " + e.Message;

                this.AddMessage(message, System.Drawing.Color.Red);
            }
        }

        private delegate void AddMessageCallback(string sMessage, Color color);

        public void AddMessage(string sMessage, Color color)
        {
            try
            {
                if (this.InvokeRequired)
                {
                    AddMessageCallback callback = new AddMessageCallback(AddMessage);
                    this.Invoke(callback, new object[] { sMessage, color });
                    return;
                }

                ListViewItem newMessage = this.lvMessages.Items.Add(sMessage);
                newMessage.SubItems.Add(DateTime.Now.ToString());
                newMessage.BackColor = color;

                this.ServerTabControl.TabPages[1].Text = "Messages (" + this.lvMessages.Items.Count.ToString() + ")";
            }
            catch (Exception e)
            {
                //TODO handle better

                string message = "Method: ServerForm.AddMessage";
                message += "\nException: " + e.Message;

                this.AddMessage(message, System.Drawing.Color.Red);
            }
        }

        private void lvMessages_DoubleClick(object sender, EventArgs e)
        {
            try
            {
                if (this.lvMessages.SelectedItems.Count == 1)
                {
                    MessageBox.Show(this.lvMessages.SelectedItems[0].Text);
                }
            }
            catch (Exception ex)
            {
                //TODO handle better

                string message = "Method: ServerForm.lvMessages_DoubleClick";
                message += "\nException: " + ex.Message;

                this.AddMessage(message, System.Drawing.Color.Red);
            }
        }
    }
}
